/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package app.gui;

import app.gui.scene.SceneHolder;
import app.gui.scene.SceneObserver;

import com.app.ThreadManager;
import com.app.client.Client;
import com.app.client.ServerHandler;
import com.app.game.chat.Message;
import com.app.game.other.Player;
import com.app.game.other.PlayerFix;
import com.app.observers.ServerObserver;
import com.app.server.Server;
import java.net.InetAddress;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import javafx.application.Platform;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.ListView;
import javafx.scene.control.TextField;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Priority;
import javafx.scene.layout.VBox;

/**
 *
 * @author Maciej Strychalski
 * @author Rafał Tomaszewicz
 */
public class Room extends SceneHolder implements ServerObserver {

    private String creditLabel = "Suma początkowa:";
    private String timeLabel = "Czas na rundę (w minutach):";
    private TextField creditField, timeField;
    private Button backButton, readyButton;
    private ListView<String> playerList;
    private SceneHolder tableHolder;
    private ChatPanel chat;
    private Client client;
    private Server server;
    private Player player;
    private ServerHandler handler;
    private boolean hostMode = false;
    private HashMap<Integer, Player> players = new HashMap<>();
    private HashMap<Integer, Boolean> readys = new HashMap<>();

    /*
     * Client contructor
     */
    public Room(SceneHolder prevHolder, Player player, String host) {
        this.player = player;
        
        client = new Client(9090, host, player);
        client.connect(9090, host, player);
        handler = this.player.getServerHandler();
        init(prevHolder);

    }
    /*
     * server contructor
     */

    public Room(SceneHolder prevHolder, Player player,boolean local) {


        server = new Server(9090,local);
        ThreadManager.getInstance().execute(server);

        client = new Client(9090, timeLabel, player);
        try {
            this.player = client.connect(9090, "localhost", player);
        } catch (Exception e) {
            e.printStackTrace();
        }

        handler = this.player.getServerHandler();

        //this.player.ready();
        //ThreadManager.getInstance().execute(client);
        System.out.println("ok");
        init(prevHolder);
    }

    private void init(SceneHolder prevHolder) {
        this.previousHolder = prevHolder;
        Label creditLbl = new Label(creditLabel);
        creditField = new TextField("1000");
        creditField.setEditable(false);
        Label timeLbl = new Label(timeLabel);
        timeField = new TextField("5");
        timeField.setEditable(false);
        VBox creditBox = new VBox(5);
        creditBox.setMaxWidth(buttonWidth);
        creditBox.getChildren().setAll(creditLbl, creditField);
        VBox timeBox = new VBox(5);
        timeBox.setMaxWidth(buttonWidth);
        timeBox.getChildren().setAll(timeLbl, timeField);

        VBox innerVb = new VBox(10);
        innerVb.setAlignment(Pos.CENTER_LEFT);
        innerVb.getChildren().setAll(creditBox, timeBox);
        innerVb.setPadding(new Insets(spacing / 2, spacing / 2, 0, 0));
        backButton = new Button("Powrót");
        backButton.setOnAction(new EventHandler<ActionEvent>() {

            @Override
            public void handle(ActionEvent arg0) {
                nextScene = Room.this.previousHolder.getScene();
                ThreadManager.getInstance().stopAll();
                notifyObservers();
            }
        });
        readyButton = new Button("Gotowy");
        readyButton.setOnAction(new EventHandler<ActionEvent>() {

            @Override
            public void handle(ActionEvent arg0) {
                Room.this.handler.sendReady();

            }
        });

        HBox buttonBox = new HBox(spacing);
        buttonBox.setPadding(new Insets(spacing, spacing / 2, spacing / 2, 0));
        buttonBox.getChildren().setAll(backButton, readyButton);
        BorderPane innerBorder = new BorderPane();
        innerBorder.setCenter(innerVb);
        innerBorder.setBottom(buttonBox);

        BorderPane border = new BorderPane();
        VBox vb = new VBox(10);
        vb.setPadding(new Insets(spacing / 2, spacing, spacing / 2, spacing / 2));
        playerList = new ListView<>();
        chat = new ChatPanel(this.player);
        this.player.getServerHandler().registerObserver(chat);
        this.player.getServerHandler().registerObserver(this);
        vb.getChildren().setAll(playerList, chat.getChat());
        VBox.setVgrow(playerList, Priority.ALWAYS);
        border.setCenter(vb);
        border.setRight(innerBorder);
        scene = new Scene(border, rootWidth, rootHeigh);

    }

    /**
     * @return the hostMode
     */
    public boolean isHostMode() {
        return hostMode;
    }

    /**
     * @param hostMode the hostMode to set
     */
    public void setHostMode(boolean hostMode) {
        timeField.setEditable(hostMode);
        creditField.setEditable(hostMode);
        this.hostMode = hostMode;
    }

    @Override
    public void updatePlayer(Player player) {
        //this.player = player;
    }

    @Override
    public void updatePlayers(final HashMap<Integer, Player> playerlist) {
        Platform.runLater(new Runnable() {

            @Override
            public void run() {
                Set set = playerlist.entrySet();
                Iterator i = set.iterator();
                while (i.hasNext()) {
                    Map.Entry<Integer, Player> entry = (Map.Entry<Integer, Player>) i.next();
                    if (!Room.this.players.containsKey(entry.getKey())) {
                        Room.this.players.put(entry.getKey(), entry.getValue());
                        Room.this.readys.put(entry.getKey(), false);
                    }
                    StringBuffer sb = new StringBuffer();
                    sb.append(entry.getValue().getName());
                    if (!readys.get(entry.getKey())) {
                        sb.append(" (nie gotowy)");
                    }
                    playerList.getItems().add(sb.toString());

                }
            }
        });
    }

    @Override
    public void updateResult(Integer result) {
    }

    @Override
    public void updateReadyNotification(Integer playerId) {
        readys.put(playerId, true);
        Platform.runLater(new Runnable() {

            @Override
            public void run() {

                Iterator i = players.entrySet().iterator();
                playerList.getItems().clear();
                int readyCounter = 0;
                while (i.hasNext()) {
                    Map.Entry<Integer, Player> entry = (Map.Entry<Integer, Player>) i.next();
                    StringBuilder sb = new StringBuilder();
                    sb.append(entry.getValue().getName());
                    if (!readys.get(entry.getKey())) {
                        sb.append(" (nie gotowy)");
                    } else {
                        ++readyCounter;
                    }
                    playerList.getItems().add(sb.toString());
                }

            }
        });


    }

    @Override
    public void updateMessage(Message msg) {
    }

    @Override
    public void updateGameStarting() {
        Platform.runLater(new Runnable() {

            @Override
            public void run() {
                //player.setServerHandler(handler);
                Game g = new Game(player, previousHolder);
                for(SceneObserver ob : observers){
                	g.registerObserver(ob);
                }
                nextScene = g.getScene();
                notifyObservers();
            }
        });

    }

    @Override
    public void updateGameOver() {
    }

    @Override
    public void reUpdatePlayer(PlayerFix player) {
        
    }

    @Override
    public void updateRoundDoneNotification(Integer playerId) {
        
    }

	@Override
	public void updatePlayerLeft(Integer player) {
		// TODO Auto-generated method stub
		
	}
}
